package f.h.dragon.howTomcatWorks;

import static f.h.dragon.util.CloseableUtil.close;
import static f.h.dragon.util.OutUtil.*;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Date;

/**
 * ServerSocketer: test for server socket
 *
 * @author Wenlong Meng(wenlong.meng@gmail.com)
 * @version 1.0 at 2012/03/04
 * @since 1.0
 */
public class ServerSocketer {

	//local variables
	/**
	 * the port of server
	 */
	private int port;
	/**
	 * backlog
	 */
	private int backlog;
	/**
	 * the host of server
	 */
	private String host;
	/**
	 * server socket
	 */
	private ServerSocket serverSocket;
	
	//Constructor
	/**
	 * 构建制定端口、backlog、主机的服务端Socket对象
	 * 
	 * @param port - 端口
	 * @param backlog - 队列数
	 * @param host - 主机
	 */
	public ServerSocketer(int port, int backlog, String host) {
		this.port = port;
		this.backlog = backlog;
		this.host = host;
	}
	
	/**
	 * 初始化服务端
	 */
	public void init(){
		outln("init Server: " + this.host + ":" + this.port + " backlog = " + this.backlog);
		try {
			this.serverSocket = new ServerSocket(this.port, this.backlog, InetAddress.getByName(this.host));
		} catch (UnknownHostException e) {
			throw new RuntimeException(e);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		outln("Server is started!");
	}
	
	/**
	 * 处理请求
	 */
	public void process(){
		outln("process...");
		try {
			//
			Socket socket = this.serverSocket.accept();
			//处理请求
			this.receive(socket);
			//构建响应msg
			StringBuilder sb = new StringBuilder();
			sb.append("<html>");//响应实体
			sb.append("<head>");
			sb.append("<title>HTTP Response Example</title>");
			sb.append("</head>");
			sb.append("<body>");
			sb.append("Welcome to Brainy Software.");
			sb.append("</body>");
			sb.append("</html>");
			//send msg
			this.send(socket, sb.toString(), true);
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
		outln("processed!");
	}

	/**
	 * 发送信息
	 * 
	 * @param msg
	 * @return
	 */
	public boolean send(Socket socket, String msg, boolean autoflush){
		outln("send msg = " + msg);
		OutputStream os = null;
		PrintWriter out = null;
		try {
			os = socket.getOutputStream();
			out = new PrintWriter(os, autoflush);
			//send an HTTP request to the web server
			out.println("HTTP/1.1 200 OK");
			out.println("Server: Tomcat");
			out.println("Date: " + new Date().toString());
			out.println("Content-Type: text/html");
			out.println("Last-Modified: " + new Date().toString());
			out.println("Content-Length: 333");
			out.println();//响应头与响应实体分隔符：CRLF
			out.println(msg);//响应实体
		} catch (IOException e) {
			throw new RuntimeException(e);
		}finally{
			//释放资源
			close(os);
			close(out);
		}
		outln("sent!");
		return true;
	}
	
	/**
	 * 接收信息
	 * 
	 * @param msg
	 * @return
	 */
	public String receive(Socket socket){
		outln("receive...");
		BufferedReader in = null;
		try {
			// in stream
			in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			//read the response
			StringBuilder sb = new StringBuilder(8096);
			if(in.ready()){
				int i = 0;
				while(i != -1){
					i = in.read();
					sb.append((char)i);
				}
			}
			outln("==============");
			Thread.sleep(50);
			outln(sb.toString());//out msg
			outln("received!");
			return sb.toString();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}finally{
			close(in);
		}
		
	}
}
